package com.email.box.utils;


import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author lixuan
 */
public class CompareFieldsUtil {

    /**
     * 实体类对比
     *
     * @param newEntity
     * @param oldEntity
     * @param filedInfo
     * @param isContainsKey 正选||反选
     * @return
     */
    public static Map<String, List<Object>> compareFields(Object newEntity, Object oldEntity, Map<String, String> filedInfo, Boolean isContainsKey) {
        try {

            Map<String, List<Object>> map = new HashMap<>(16);

            // 只有两个对象都是同一类型的才有可比性
            if (newEntity.getClass() == oldEntity.getClass()) {
                Class clazz = newEntity.getClass();
                // 获取object的属性描述
                PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                        Object.class).getPropertyDescriptors();
                // 属性对比
                for (PropertyDescriptor pd : pds) {
                    // 属性名
                    String name = pd.getName();
                    // 是否当前属性选择进行比较，否跳到下一次循环
                    if (filedInfo != null && (filedInfo.containsKey(name) && isContainsKey)) {
                        // get方法
                        Method readMethod = pd.getReadMethod();
                        // 在objBefore上调用get方法等同于获得objBefore的属性值
                        Object objBefore = readMethod.invoke(oldEntity);
                        // 在objAfter上调用get方法等同于获得objAfter的属性值
                        Object objAfter = readMethod.invoke(newEntity);

                        //判断开始
                        if (objBefore == null && objAfter == null) {
                            continue;
                        } else if (objBefore == null && objAfter != null) {
                            List<Object> list = new ArrayList<Object>();
                            list.add(filedInfo.get(name));
                            list.add(objBefore);
                            list.add(objAfter);
                            map.put(name, list);
                            continue;
                        }
                        // 比较这两个值是否相等,不等则放入map
                        if (!objBefore.equals(objAfter)) {
                            List<Object> list = new ArrayList<Object>();
                            list.add(filedInfo.get(name));
                            list.add(objBefore);
                            list.add(objAfter);
                            map.put(name, list);
                        }
                    }
                }
            }
            return map;
        } catch (Exception e) {
            return null;
        }
    }
}



